From 8606e57910fb3ea4c66448702ee7e3bb73f3c29d Mon Sep 17 00:00:00 2001 From: Paolo Borelli Date: Thu, 29 Oct 2015 17:20:54 +0100 Subject: [PATCH] win32: handle WM_DISPLAYCHANGE globally Instead of handling WM_DISPLAYCHANGE on every GdkWindow, only handle it on an ad-hoc hidden window we create when opening the display. This has two reasons: 1) we want emit the display::size-changed signal even if there are no gtk windows currently open 2) we want to emit the signal just once and not once for every window https://bugzilla.gnome.org/show_bug.cgi?id=757324 --- gdk/win32/gdkdisplay-win32.c | 84 +++++++++++++++++++++++++++++++++++- gdk/win32/gdkdisplay-win32.h | 2 + gdk/win32/gdkevents-win32.c | 12 ------ 3 files changed, 84 insertions(+), 14 deletions(-) diff --git a/gdk/win32/gdkdisplay-win32.c b/gdk/win32/gdkdisplay-win32.c index 0a47970cd5..b1e6f01ef6 100644 --- a/gdk/win32/gdkdisplay-win32.c +++ b/gdk/win32/gdkdisplay-win32.c @@ -26,6 +26,8 @@ #include "gdkwin32window.h" #include "gdkwin32.h" +static int debug_indent = 0; + /** * gdk_win32_display_set_cursor_theme: * @display: (type GdkWin32Display): a #GdkDisplay @@ -242,6 +244,81 @@ _gdk_monitor_init (void) } } +static LRESULT CALLBACK +inner_display_change_window_procedure (HWND hwnd, + UINT message, + WPARAM wparam, + LPARAM lparam) +{ + switch (message) + { + case WM_DESTROY: + { + PostQuitMessage (0); + return 0; + } + case WM_DISPLAYCHANGE: + { + _gdk_monitor_init (); + _gdk_root_window_size_init (); + g_signal_emit_by_name (_gdk_screen, "size_changed"); + + return 0; + } + default: + /* Otherwise call DefWindowProcW(). */ + GDK_NOTE (EVENTS, g_print (" DefWindowProcW")); + return DefWindowProc (hwnd, message, wparam, lparam); + } +} + +static LRESULT CALLBACK +display_change_window_procedure (HWND hwnd, + UINT message, + WPARAM wparam, + LPARAM lparam) +{ + LRESULT retval; + + GDK_NOTE (EVENTS, g_print ("%s%*s%s %p", + (debug_indent > 0 ? "\n" : ""), + debug_indent, "", + _gdk_win32_message_to_string (message), hwnd)); + debug_indent += 2; + retval = inner_display_change_window_procedure (hwnd, message, wparam, lparam); + debug_indent -= 2; + + GDK_NOTE (EVENTS, g_print (" => %" G_GINT64_FORMAT "%s", (gint64) retval, (debug_indent == 0 ? "\n" : ""))); + + return retval; +} + +/* Use a hidden window to be notified about display changes */ +static void +register_display_change_notification (GdkDisplay *display) +{ + GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display); + WNDCLASS wclass = { 0, }; + ATOM klass; + + wclass.lpszClassName = "GdkDisplayChange"; + wclass.lpfnWndProc = display_change_window_procedure; + wclass.hInstance = _gdk_app_hmodule; + + klass = RegisterClass (&wclass); + if (klass) + { + display_win32->hwnd = CreateWindow (MAKEINTRESOURCE (klass), + NULL, WS_POPUP, + 0, 0, 0, 0, NULL, NULL, + _gdk_app_hmodule, NULL); + if (!display_win32->hwnd) + { + UnregisterClass (MAKEINTRESOURCE (klass), _gdk_app_hmodule); + } + } +} + GdkDisplay * _gdk_win32_display_open (const gchar *display_name) { @@ -276,6 +353,8 @@ _gdk_win32_display_open (const gchar *display_name) /* Precalculate display name */ (void) gdk_display_get_name (_gdk_display); + register_display_change_notification (_gdk_display); + g_signal_emit_by_name (_gdk_display, "opened"); GDK_NOTE (MISC, g_print ("... _gdk_display now set up\n")); @@ -376,7 +455,6 @@ gdk_win32_display_supports_selection_notification (GdkDisplay *display) } static HWND _hwnd_next_viewer = NULL; -static int debug_indent = 0; /* * maybe this should be integrated with the default message loop - or maybe not ;-) @@ -619,7 +697,6 @@ gdk_win32_display_flush (GdkDisplay * display) GdiFlush (); } - static void gdk_win32_display_sync (GdkDisplay * display) { @@ -631,6 +708,9 @@ gdk_win32_display_sync (GdkDisplay * display) static void gdk_win32_display_dispose (GObject *object) { + GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (object); + + g_clear_pointer(&display_win32->hwnd, (GDestroyNotify)DestroyWindow); } static void diff --git a/gdk/win32/gdkdisplay-win32.h b/gdk/win32/gdkdisplay-win32.h index 585d958890..8cb08614fe 100644 --- a/gdk/win32/gdkdisplay-win32.h +++ b/gdk/win32/gdkdisplay-win32.h @@ -31,6 +31,8 @@ struct _GdkWin32Display int cursor_theme_size; GHashTable *cursor_cache; + HWND hwnd; + /* WGL/OpenGL Items */ guint have_wgl : 1; guint gl_version; diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c index 0390a1ed42..2ce139f868 100644 --- a/gdk/win32/gdkevents-win32.c +++ b/gdk/win32/gdkevents-win32.c @@ -1611,14 +1611,6 @@ sync_timer_proc (HWND hwnd, KillTimer (hwnd, sync_timer); } -static void -handle_display_change (void) -{ - _gdk_monitor_init (); - _gdk_root_window_size_init (); - g_signal_emit_by_name (_gdk_screen, "size_changed"); -} - static gboolean handle_nchittest (HWND hwnd, GdkWindow *window, @@ -3202,10 +3194,6 @@ gdk_event_translate (MSG *msg, return_val = TRUE; break; - case WM_DISPLAYCHANGE: - handle_display_change (); - break; - case WM_DWMCOMPOSITIONCHANGED: _gdk_win32_window_enable_transparency (window); break; -- 2.30.2